<?php

namespace addons\member\model;

use web\common\service\Credential;

/**
 * 会员账户信息
 * @author shilinqing
 */
class MemberAccountModel extends \web\common\model\BaseModel {

    protected function _initialize() {
        $this->tableName = 'member_account';
    }

    /**
     * 判断id是否存在
     */
    public function idExists($id){
        return $this->where('id',$id)->value('id');
    }

    /**
     * 获取节点id
     * @param type $id
     * @return type
     */
    public function getChildsByPID($pid) {
        $where['pid'] = $pid;
        return $this->where($where)->field('id,pid,username')->select();
    }


    /**
     * 获取节点id 
     * @param type $id
     * @return type
     */
    public function getChildssByPID($pid) {
        $list = $this->field('id,username,phone,real_name')->where('pid',$pid)->select();
        if($list){
            foreach ($list as &$value){
                if($value['real_name'] == null){
                    $value['real_name'] = '未认证';
                }
            }
        }
        return $list;
    }

//    /**
//     * 获取节点id
//     * @param type $id
//     * @return type
//     */
//    public function getChildssByPID($pid) {
//        $list = $this->alias('m')->join('member_physical_contribution c','c.user_id=m.id')->join('member_pool p','p.user_id=m.id','left')->field('m.id,pid,username,push_total,team_strength,(flow_total+flow_single) shop_ach,gratitude_pool')->where('pid',$pid)->select();
//        foreach ($list as $key => &$v) {
//            $v['team_strength']+=0;
//            $v['shop_ach']+=0;
//            $v['gratitude_pool']+=0;
//        }
//        return $list;
//    }

    /**
     * 用户名或手机号登陆
     * @param type $password
     * @param type $phone
     * @param type $wallet_name
     * @return boolean
     */
    public function getLoginPhoneAndUsernameData($password, $country_code, $phone = '', $fields = 'id,username,email,is_frozen') {
        $sql = 'select ' . $fields . ' from ' . $this->getTableName() . ' where logic_delete=0';
        if (!empty($phone)) {
            $sql .= ' and (phone=\'' . $phone . '\')';

        }
        $sql .= ' and password=\'' . md5($password) . '\'';
        $result = $this->query($sql);
        if (!empty($result) && count($result) > 0)
            return $result[0];
        else
            return null;
    }

    /**
     * 根据用户名获取用户id
     * @param type $username
     * @return type
     */
    public function getUserIDByUsername($username) {
        $where['username'] = $username;
        return $this->where($where)->value('id');
    }

    public function getList($pageIndex = -1, $pageSize = -1, $filter = '', $order = 'id desc') {
        $sql = 'select * from (select m.*,a.username to_user from ' . $this->getTableName() .' m left join tp_member_account a on m.pid=a.id) y ';
        if (!empty($filter)) {
            $sql = $sql . ' where ' . $filter;
        }
        return $this->getDataListBySQL($sql, $pageIndex, $pageSize, $order);
    }

    /**
     * get user login info . (filed phone and wallet_name) one of them has to be filled out
     * @param type $password
     * @param type $phone
     * @param type $wallet_name
     * @param type $fields
     * @return boolean
     */
    public function getLoginData($password, $phone = '', $fields = 'id,username,address,is_auth', $both = false) {
        $sql = 'select ' . $fields . ' from ' . $this->getTableName() . ' where logic_delete=0';
        if (!empty($phone)) {
            if ($both) {
                $sql .= ' and (phone=\'' . $phone . '\')';
            } else {
                $sql .= ' and phone=\'' . $phone . '\'';
            }
        }
        $sql .= ' and password=\'' . md5($password) . '\'';
        $result = $this->query($sql);
        if (!empty($result) && count($result) > 0)
            return $result[0];
        else
            return null;
    }


    /**
     * get user login info . (filed phone and wallet_name) one of them has to be filled out
     * @param type $password
     * @param type $phone
     * @param type $wallet_name
     * @param type $fields
     * @return boolean
     */
    public function getLoginUsernameData($password, $phone = '', $fields = 'id,username,address,is_auth', $both = false) {
        $sql = 'select ' . $fields . ' from ' . $this->getTableName() . ' where logic_delete=0';
        if (!empty($phone)) {
            if ($both) {
                $sql .= ' and username=\'' . $phone . '\'';
            } else {
                $sql .= ' and phone=\'' . $phone . '\'';
            }
        }
        $sql .= ' and password=\'' . md5($password) . '\'';
        $result = $this->query($sql);
        if (!empty($result) && count($result) > 0)
            return $result[0];
        else
            return null;
    }

    /**
     * 短信验证登录时 只有电话号码用来查询用户信息
     * get user login info . filed phone  has to be filled out
     * @param type $phone
     * @param type $fields
     * @return boolean
     */
    public function getLoginDataBySms($phone = '', $fields = 'id,username,address,is_auth') {
        $sql = 'select ' . $fields . ' from ' . $this->getTableName() . ' where logic_delete=0';
        if (!empty($phone)) {
            $sql .= ' and phone=\'' . $phone . '\'';
        } else {
            return false;
        }
        $result = $this->query($sql);
        if (!empty($result) && count($result) > 0)
            return $result[0];
        else
            return null;
    }

    /**
     * verify the user's phone is registered or not
     * @param type $phone
     * @return type
     */
    public function hasRegsterPhone($phone) {
        $where['phone'] = $phone;
        return $this->where($where)->count();
    }

    /**
     * @param $email
     * @return mixed
     */
    public function hasRegsterEmail($email) {
        $where['email'] = $email;
        return $this->where($where)->count();
    }

    /**
     * verify the user's username is registered or not
     * @param type $phone
     * @return type
     */
    public function hasRegsterUsername($username) {
        $where['username'] = $username;
        return $this->where($where)->count();
    }

    /*
     * 验证交易密码
     */
    public function checkPayPwd($userId,$payPassword)
    {
        $bool = $this->where(['id'=>$userId,'pay_password'=>md5($payPassword)])->value('id');
        if ($bool) return true;
        return false;
    }

    /*
     * 验证钱包密码
     */
    public function checkPwd($userId,$payPassword)
    {
        $bool = $this->where(['id'=>$userId,'password'=>md5($payPassword)])->value('id');
        if ($bool) return true;
        return false;
    }

    /*
     * 验证交易密码
     */
    public function checkPayPwdLevel($userId,$payPassword)
    {
        $bool = $this->field('*')->where(['id'=>$userId,'pay_password'=>md5($payPassword)])->find();
        if ($bool) return $bool;
        return false;
    }

    /**
     * update the user password by phone number
     * @param type $phone
     * @param type $password
     * @param type $type 2=login password ,3 = payment password
     * @return int
     */
    public function updatePassByUserID($id, $password, $type = 2) {
        if ($type == 2) {
            $data['password'] = $password;
        } else if ($type == 3) {
            $data['pay_password'] = $password;
        } else {
            return 0;
        }
        $where['id'] = $id;
        return $this->where($where)->update($data);
    }
    
    /**
     * update the user password by phone number
     * @param type $phone
     * @param type $password
     * @param int $account_type
     * @param type $type 2=login password ,3 = payment password
     * @return int
     */
    public function updatePassByPhone($phone, $password, $type = 2, $account_type = 1) {
        if ($type == 2) {
            $data['password'] = $password;
        } else if ($type == 3) {
            $data['pay_password'] = $password;
        } else {
            return 0;
        }
        if($account_type == 1){
            $where['phone'] = $phone;
        }else{
            $where['email'] = $phone;
        }
        return $this->where($where)->update($data);
    }

    /**
     * get user by invite email
     * @param type $email
     * @return int
     */
    public function getUserByEmail($email) {
        $where['email'] = $email;
        $res = $this->where($where)->field('id')->find();
        if (!empty($res)) {
            return $res['id'];
        } else {
            return 0;
        }
    }

    /**
     * get user by invite code
     * @param type $invite_code
     * @return int
     */
    public function getUserIDByInviteCode($invite_code) {
        $where['invite_code'] = $invite_code;
        $where['logic_delete'] = 0;
        return $this->where($where)->value('id');
    }

    /**
     * get user by invite code
     * @param type $invite_code
     * @return int
     */
    public function getInfoByInviteCode($invite_code) {
        $where['invite_code | phone'] = $invite_code;
        $where['logic_delete'] = 0;
        return $this->field('id,pid_path')->where($where)->find();
    }

    /**
     * get user parent id
     * @param type $user_id
     * @return type
     */
    public function getPID($id) {
        $where['id'] = $id;
        $ret = $this->where($where)->field('pid')->find();
        return $ret['pid'];
    }

    public function getPids($id, $pids = '',$is_guanli = false ,$i = 0) {
        $pid = $this->getPID($id);
        if (!empty($pid)) {
            if ($pids != '')
                $pids .= ',';
            $pids .= $pid;
            if($is_guanli == true){
                $i++;
            }
            if($i == 80){
                return $pids;
            }
            return $this->getPids($pid, $pids,$is_guanli,$i);
        }else {
            return $pids;
        }
    }

    /**
     * 获取下级
     */
    public function getChilds($id,$limit,$arr){
        if($limit == 6){
            return $arr;
        }
        $limit++;
        $where['pid'] = ['in',$id];
        $ret = $this->where($where)->field('group_concat(id) as ids')->find();
        if(empty($ret)) return $arr;
        else{
            $arr .=','.$ret['ids'];
            $arr = implode(',', array_unique(array_filter(explode(',', $arr)))) ;
            return $this->getChilds($arr,$limit,$arr);
        }
    }


    /**
     * get user by the username
     * @param type $address
     * @return int
     */
    public function getUserByUsername($username) {
        $where['username'] = $username;
        $data = $this->where($where)->find();
        if (!empty($data)) {
            return $data['id'];
        } else {
            return 0;
        }
    }

    /**
     * get user by the phone
     * @param type $address
     * @return int
     */
    public function getUserByPhone($phone) {
        $where['phone'] = $phone;
        $where['logic_delete'] = 0;
        $data = $this->where($where)->find();
        return $data;
    }

    /**
     * return user authentication status
     * @param type $id
     */
    public function getAuthByUserID($id) {
        $where['id'] = $id;
        $auth = $this->where($where)->field('is_auth')->find();
        return $auth['is_auth'];
    }

    /**
     * change user account frozen status
     * @param type $id
     * @param type $status default 1
     * @return type
     */
    public function changeFrozenStatus($id, $status = 1) {
        $where['id'] = $id;
        $data['is_frozen'] = $status;
        return $this->where($where)->update($data);
    }

    /*
     * openId获取用户资料
     */
    public function getIDByOpenid($openid, $field = 'id,head_img,username,country_code,phone,invite_code') {
        $where['open_id'] = $openid;
        $data = $this->where($where)->field($field)->find();
        return $data;
    }

    /**
     * get user authentication data
     * @param type $id
     * @param type $fields
     * @return type
     */
    public function getAuthData($id, $fields = 'is_auth,real_name,card_no,id_face,id_back,id_stand,id_handheld') {
        $where['id'] = $id;
        return $this->where($where)->field($fields)->find();
    }

    /**
     * 判断父级是否是上线
     */
    public function findPid($id,$target_id){
        $pid = $this->where('id',$id)->value('pid');
        if($pid==0){
            return true;
        }
        if($pid==$target_id){
            return false;
        }
        return $this->findPid($pid,$target_id);
    }

    /**
     * 根据地址获取ID
     */
    public function getUserByAddr($eth_addr){
        return $this->where('yuan_address',$eth_addr)->value('id');
    }

    /**
     * 根据手机号获取ID
     */
    public function getUserByAddrPhone($eth_addr){
        return $this->where('phone',$eth_addr)->value('id');
    }

    /**
     * 获取下代人数
     */
    public function getDeepNumber($ids){
        if(empty($ids)){
            $data['ids'] = [];
            $data['count'] = 0;
        }else{
            if(is_array($ids)){
                $arr = [];
                foreach ($ids as $k => $v) {
                    $arr[] = $v['id'];
                }
            }else{
                $arr = $ids;
            }
            $data['ids'] = $this->field('id')->where(['pid'=>['in',$arr]])->select();
            $data['count'] = $this->field('id')->where(['pid'=>['in',$arr]])->count();
        }
        return $data;
    }

    /**
     * @param $phone
     * @return mixed
     */
    public function getUserIDByPhone($phone) {
        $where['phone'] = $phone;
        return $this->where($where)->value('id');
    }

    public function getTeamList($pageIndex = -1, $pageSize = -1, $filter = '', $fileds='*', $order = 'id asc') {
        $sql = 'select '.$fileds.' from ' . $this->getTableName() .' a left join tp_physical_contribution b on b.user_id=a.id where ';
        if (!empty($filter))
            $sql .=  ' '.$filter;
        return $this->getDataListBySQL($sql, $pageIndex, $pageSize, $order);
    }

    public function getTeamTotal($filter = ''){
        $sql = 'select count(a.id) c from ' . $this->getTableName() .' a left join tp_physical_contribution b on b.user_id=a.id where ';
        if (!empty($filter))
            $sql .=  ' '.$filter;
        $data = $this->query($sql);
        if($data){
            return $data[0]['c'];
        }else{
            return 0;
        }
    }

    public function getInviteTree($id) {

        $ids = $id;
        while ($id != ''){
            $where['pid'] = array('in',$id);
            $pids = $this->where($where)->field('group_concat(id) pids')->find();
            if(!empty($pids)){
                $pids = $pids['pids'];
                if($ids != ''){
                    $ids .= ',';
                }
                $ids .= $pids;

            }
            $id = $pids;

        }
        $ids = substr($ids, 0,strlen($ids)-1);
        return $ids;
    }


    /**
     * 后台用户列表
     * @param int $pageIndex
     * @param int $pageSize
     * @param string $filter
     * @param string $fileds
     * @param string $order
     * @return mixed
     */
    public function getMemberList($pageIndex = -1, $pageSize = -1, $filter = '',$fileds='*', $order = 'a.id desc') {
        $userM = new \addons\member\model\MemberAccountModel();
        $sql = 'select '.$fileds.' from '.$this->getTableName() . ' a left join '.$userM->getTableName().' b on a.pid=b.id ';
        if($filter != ''){
            $sql .= ' where '.$filter;
        }
        return $this->getDataListBySQL($sql, $pageIndex, $pageSize, $order);
    }

    /**
     * 后台用户列表 获取记录总数
     * @param string $filter
     * @return int
     */
    public function getMemberTotal($filter = '') {
        $userM = new \addons\member\model\MemberAccountModel();
        $sql = 'select count(a.id) as c from '.$this->getTableName() . ' a left join '.$userM->getTableName().' b on a.pid=b.id left join tp_level_config level on level.level=a.level';

        if($filter != ''){
            $sql .= ' where '.$filter;
        }
        $result = $this->query($sql);
        if (count($result) > 0)
            return intval($result[0]['c']);
        else
            return 0;
    }


    /**
     * 获取推荐人数
     */
    public function getPushTotal($user_id){
        $count = $this->alias('m')->join('member_physical_contribution c','c.user_id=m.id')->where('pid',$user_id)->count();
        // dump($count);
        $sum = $this->alias('m')->join('member_physical_contribution c','c.user_id=m.id')->where('pid',$user_id)->sum('push_total');
        // dump($this->getLastSql());
        // dump($sum);
        return ($count+$sum);
    }



    /**
     * 公共注册
     */
    public function commonRegister($username,$auxiliary_device,$private_key,$invite_user_id,$password,$password_tips=''){
        $this->startTrans();
        $data['username'] = $username;
        $data['nickname'] = $username;
        $data['password'] = md5($password);
        $data['auxiliary_device'] = $auxiliary_device;
        $data['private_key'] = $private_key;
        $data['password_tips'] = $password_tips;
        $data['head_img'] = '/uploads/slider/20201112/head.png';
        $data['register_time'] = NOW_DATETIME;
        $data['phone'] = time();
        $data['pid'] = $invite_user_id['id'];
        if(!empty($invite_user_id['pid_path'])){
            $pid_path = $invite_user_id['pid_path'].$invite_user_id['id'].',';
        }else{
            $pid_path = ','.$invite_user_id['id'].',';
        }
        $data['pid_path'] = $pid_path;
        $data['invite_code'] = createRandCode(6);
        $user_id = $this->add($data);
        if (!$user_id) {
            $this->rollback();
            return $this->failData(lang('LOGIN_REG_FAIL'));
        }
        $phyM = new \addons\member\model\MemberAchievement();
        $res = $phyM->createPhy($user_id);
        if (!$res) {
            $this->rollback();
            return $this->failData("生成业绩记录失败");
        }
        $res = $phyM->addPhy($pid_path,1,1);
        if (!$res) {
            $this->rollback();
            return $this->failData("添加业绩记录失败");
        }
        $res = (new MnemonicWords)->setUsed($auxiliary_device,$private_key);
        if (!$res) {
            $this->rollback();
            return $this->failData("该助记词已被使用");
        }
        $balanceM = new \addons\member\model\Balance();
        $type_list = (new \addons\config\model\BalanceConf)->getDataList(-1, -1, '', 'id', 'id asc');
        foreach ($type_list as $k => $type) {
            $_balance['user_id'] = $user_id;
            $_balance['type'] = $type['id'];
            $_balance['update_time'] = NOW_DATETIME;

            $credential = Credential::create();
            $address = (string)$credential->address();
            $_balance['privatekey'] = $credential->privateKey();
            $_balance['pass'] = $credential->publicKey();
            $_balance['address'] = $address;

            $balanceM->add($_balance);
        }
        $this->commit();
        return $this->successData($user_id);
    }
}
